#ifndef GERADOR_H_
#define GERADOR_H_

#include <iostream>
#include <list>
#include <vector>

#include "Hash.h"
#include "ListaTokens.h"
#include "Arvore.h"
#include "NoArvore.h"
#include "NoAux.h"
#include <iomanip>

#include "Identificador.h"
#include "IdentificadorProcFunc.h"
#include "IdentificadorVariavel.h"
#include "IdentificadorParametro.h"

#include <sstream>

class Gerador
{
    public:
       Gerador(); 
       ~Gerador();
       
       bool geraCodigo(Arvore *pArvore, Hash *pHash);
       void imprime(std::ostream& saida);
    
    private:
        Hash *mTabelaHash;
	Arvore *mArvore;
        
        std::vector<std::string> rotulos;
        std::vector<std::string> comandos;
        
        int auxLaco;
        int nivelAtual;
        int numFuncaoAtual;
        
        void escreve(std::string rotulo, std::string codigo);
        void escreve(std::string codigo);
        
        void geraPrograma(NoArvore *pNoAtual);
        int contaVariaveis(NoArvore *pNoAtual);
        std::string intToString(int);
        
        bool geraComandos(NoArvore *pNoAtual);
        
        bool geraComandoIf(NoArvore *pNoAtual);
        bool geraComandoWhile(NoArvore *pNoAtual);
        bool geraComandoRead(NoArvore *pNoAtual);
        bool geraComandoWrite(NoArvore *pNoAtual);
        bool geraComandoAtribuicao(NoArvore *pNoAtual);
        
        bool geraExpressao(NoArvore *pNoAtual);
        bool geraExpressaoNormal(std::list<std::string> *pExpressao, NoArvore *pNoAtual);
        bool isNumero(std::string pIdentificador);
        bool isBooleano(std::string pIdentificador);
        std::list<NoAux*> infixaToPosfixa(std::list<NoAux*> pExpressao);
        
        std::string buscarProcedimento(std::string pIdentificador, NoArvore *pNoPai);
        
        bool geraFuncoes(NoArvore *pNoAtual);
        
        NoAux* geraArvoreExpressao(std::list<std::string> *pExpressao, NoArvore *pNoAtual);
        bool isIdentificadorFuncao(std::string ident, NoArvore *pNoAtual);
        NoAux* geraArvorePosFixa(NoAux* raiz);
        bool geraCodigoExpressao(NoAux* raiz, NoArvore *pNoAtual);
        
        bool geraChamadaProcedimento(NoArvore *pNoAtual);
};

#endif /*GERADOR_H_*/
